package gbench.sandbox.matrix.ml;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.text.MessageFormat;
import org.junit.jupiter.api.Test;
import gbench.commonApp.data.DataMatrixApp;

public class JunitML extends DataMatrixApp{
    
    String cat(Object ...oo) {
        return MessageFormat.format("{0}{1}", oo);
    }
    
    @Test
    @SuppressWarnings("static-access")
    public void foo() {
        
        var v0 = V(10,n-> (Fx) x->n);// 初阶函数向量
        var v1 = V(10,n-> (Fx) x->!n.equals(x) // n是v0调用后的处理的结果
            ? null // 非对角线的元素无效
            : (Fx) a->cat(x,n) // 仅对角线的元素有效
        );// 对v0计算结果进行复合的函数向量:1阶函数向量
        
        var ff2 = this.mmult2(v0, v1.tp());// 使用 v1复合 v0 生成 v1(v0(x))的的 函数矩阵 ,即函数的函数的矩阵,是升阶运算(右矩阵复合左矩阵)：把一阶函数升为2阶函数并排布乘一个二阶函数的矩阵
        // 打印二阶函数矩阵
        println("二阶函数矩阵");
        println(ff2);
        var ff1 = ff2.evaluate(f->(Fx)f.apply(null)); // ff 是一个10*10的函数矩阵的1阶函数矩阵:降阶运算，降为1阶函数
        // 打印一阶函数矩阵
        println("一阶函数矩阵");
        println(ff1);
        // 把一阶函数 矩阵求值乘 0阶函数矩阵：即值矩阵
        println("结果值序列");
        println ( st(e->e!=null,ff1.flc2()).collect(llclc(e->e.apply(null))) );// 提取出去费控的函数并进行求值
        
    }
    
    /**
     * 简单的全排列的实现
     */
    @Test
    public void bar() {
        /**
         * 简单的数据行
         * @author gbench
         *
         */
        class Line extends LinkedList<Integer>{
            private static final long serialVersionUID = 1L;
            public Line append(Integer n) {
                this.add(n);
                return this;
            }//append
        }// Line
        
        var p = V(10,n-> (Function<Line,Line>) line->line.append(n));
        p.mmult2(p.tp(),Function::compose,ss->ss.reduce(Function::compose));
        
        var v0 = V(10,n-> (Fx) x->((Line)x).append(n));
        var v1 = v0;
        // 全排列
        int n = 3;// 生成一个3位长的全排列向量。
        for(int i=0;i<n-1;i++) {
            var ff = mmult2(v0, v1.tp());// 数据累计追加
            v1 = V(ff.flc());// 转换成列向量继续追加
        }
        var x = v1.evaluate(f->f.apply(new Line()));
        var ai = new AtomicInteger(1);
        st(x.flc()).map(e->(Line)e).forEach(r->{
            println(MessageFormat.format("{0,number,#} ---> {1}",ai.getAndIncrement(),r));
        });
        
    }
    
    /**
     * 简单的全排列的实现
     */
    @Test
    public void qux() {
        /**
         * 简单的数据行
         * @author gbench
         *
         */
        class Line extends LinkedList<Integer>{
            private static final long serialVersionUID = 1L;
            public Line append(Integer n) {
                this.add(n);
                return this;
            }//append
        }// Line
        
        var v0 = V(10,n-> (Function<Line,Line>) line -> line.append(n) );
        var v1 = v0;
        // 全排列
        int n = 3;// 生成一个3位长的全排列向量。
        for(int i=0;i<n-1;i++) {
            v1 = V(v0.mmult2(v1.tp(),Function::compose,ss->ss.reduce(Function::compose).get()).flc());// 转换成列向量继续追加
        }
        var x = v1.evaluate(f->f.apply(new Line()));
        var ai = new AtomicInteger(1);
        st(x.flc()).map(e->(Line)e).forEach(r->{
            println(MessageFormat.format("{0,number,#} ---> {1}",ai.getAndIncrement(),r));
        });
        
    }
    
    @Test
    void foobar() {
        
      
    }

}
